package com.test;

import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class TimeCutUtil{
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");

    public static void main(String[] args) {
        String stTime = "2021-12-15 00:00:00";
        String edTime = "2022-12-15 23:59:59";
        Long startTime = dateToStamp(stTime);
        Long endTime = dateToStamp(edTime);
        // 3.开始时间段区间集合
        List<Long> beginDateList = new ArrayList<Long>();
        // 4.结束时间段区间集合
        List<Long> endDateList = new ArrayList<Long>();
        // 5.调用工具类
        String hours = "23";
        TimeCutUtil.getIntervalTimeByMonth(startTime, endTime, beginDateList, endDateList);
        /*if(StringUtils.isEmpty(hours) || "0".equals(hours)) {
            TimeCutUtil.getIntervalTimeByMonth(startTime, endTime, beginDateList, endDateList);
        }*//*else {
            Integer stHour = Integer.valueOf(hours);
            Integer edHour = (stHour == 0 ? 24 : stHour) - 1;
            TimeCutUtil.getIntervalTimeByDay2(startTime, endTime, beginDateList, endDateList, stHour, edHour);
        }*/
//	    System.out.println(beginDateList);
//	    System.out.println(endDateList);
        //TimeCutUtil.getIntervalTimeByWeek(startTime, endTime, beginDateList, endDateList);
        // 6.打印输出
        for (int i = 0; i < beginDateList.size(); i++) {
            Long beginStr = beginDateList.get(i);
            Long endStr = endDateList.get(i);
            String begin1 = sdf.format(new Date(beginStr));
            String end1 = sdf.format(new Date(endStr));
            System.out.println("该时间段内第" + (i+1) + "月--时间区间:" + begin1 + "-------" + end1);
        }
    }

    /*
     * 将时间转换为时间戳
     */
    public static Long dateToStamp(String s) {
        try {
            Date date = sdf.parse(s);
            long ts = date.getTime();
            return ts;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 以季度分割时间段
     * 此处季度是以 1-3月   4-6月   7-9月  10-12月 划分
     * @param startTime     开始时间戳(毫秒)
     * @param endTime       结束时间戳(毫秒)
     * @param beginDateList 开始段时间戳 和 结束段时间戳 一一对应
     * @param endDateList   结束段时间戳 和 开始段时间戳 一一对应
     */
    public static void getIntervalTimeByQuarter(Long startTime, Long endTime, List<Long> beginDateList, List<Long> endDateList) {
        Date startDate = new Date(startTime);
        Date endDate = new Date(endTime);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        int month = calendar.get(Calendar.MONTH) + 1;
        switch (month) {
            case 12:
            case 3:
            case 6:
            case 9:
                addTime(beginDateList, endDateList, startDate, endDate, calendar, 1);
                break;
            case 1:
            case 4:
            case 7:
            case 10:
                addTime(beginDateList, endDateList, startDate, endDate, calendar, 3);
                break;
            case 2:
            case 5:
            case 8:
            case 11:
                addTime(beginDateList, endDateList, startDate, endDate, calendar, 2);
                break;
        }
    }

    private static void addTime(List<Long> beginDateList, List<Long> endDateList, Date startDate, Date endDate, Calendar calendar, int i) {
        beginDateList.add(startDate.getTime());
        calendar.add(Calendar.MONTH, i);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.DATE, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        if (calendar.getTimeInMillis() > endDate.getTime()) {
            endDateList.add(endDate.getTime());
        } else {
            endDateList.add(calendar.getTimeInMillis());
            while (calendar.getTimeInMillis() < endDate.getTime()) {
                calendar.add(Calendar.DATE, 1);
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                beginDateList.add(calendar.getTimeInMillis());
                calendar.add(Calendar.MONTH, 3);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                calendar.add(Calendar.DATE, -1);
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                if (calendar.getTimeInMillis() < endDate.getTime()) {
                    endDateList.add(calendar.getTimeInMillis());
                } else {
                    endDateList.add(endDate.getTime());
                }
            }
        }
    }

    /**
     * 以周分割时间段
     *
     * @param startTime     开始时间戳(毫秒)
     * @param endTime       结束时间戳(毫秒)
     * @param beginDateList 开始段时间戳 和 结束段时间戳 一一对应
     * @param endDateList   结束段时间戳 和 开始段时间戳 一一对应
     */
    public static void getIntervalTimeByWeek(Long startTime, Long endTime, List<Long> beginDateList, List<Long> endDateList) {
        try {
            Date startDate = new Date(startTime);
            Calendar calendar  = Calendar.getInstance();
            calendar.setFirstDayOfWeek(Calendar.MONDAY);
            calendar.setTime(startDate);
            boolean bool = true;
            while (calendar.getTimeInMillis() <= endTime) {
                int week1 = calendar.get(Calendar.DAY_OF_WEEK) - 1;// 周几
                if (bool || week1 == 0 || week1 == 1) {
                    if (week1 == 0) {// 周日
                        calendar.set(Calendar.HOUR_OF_DAY, 23);
                        calendar.set(Calendar.MINUTE, 59);
                        calendar.set(Calendar.SECOND, 59);
                        endDateList.add(calendar.getTimeInMillis());
                    } else {
                        calendar.set(Calendar.HOUR_OF_DAY, 0);
                        calendar.set(Calendar.MINUTE, 0);
                        calendar.set(Calendar.SECOND, 0);
                        beginDateList.add(calendar.getTimeInMillis());
                    }
                    bool = false;
                }
                calendar.add(Calendar.DAY_OF_MONTH, 1);// 加一天
            }
            endDateList.add(endTime);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 按照月份分割一段时间
     *
     * @param startTime     开始时间戳(毫秒)
     * @param endTime       结束时间戳(毫秒)
     * @param beginDateList 开始段时间戳 和 结束段时间戳 一一对应
     * @param endDateList   结束段时间戳 和 开始段时间戳 一一对应
     */
    public static void getIntervalTimeByMonth(Long startTime, Long endTime, List<Long> beginDateList, List<Long> endDateList) {
        Date startDate = new Date(startTime);
        Date endDate = new Date(endTime);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        beginDateList.add(calendar.getTimeInMillis());
        while (calendar.getTimeInMillis() < endDate.getTime()) {
            calendar.add(Calendar.MONTH, 1);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            calendar.add(Calendar.DATE, -1);
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            if(calendar.getTimeInMillis() < endDate.getTime()){
                endDateList.add(calendar.getTimeInMillis());
            } else {
                endDateList.add(endDate.getTime());
                break;
            }
            calendar.add(Calendar.DATE, 1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            beginDateList.add(calendar.getTimeInMillis());
        }
    }

    /**
     * 按照天分割一段时间
     *
     * @param startTime     开始时间戳(毫秒)
     * @param endTime       结束时间戳(毫秒)
     * @param beginDateList 开始段时间戳 和 结束段时间戳 一一对应
     * @param endDateList   结束段时间戳 和 开始段时间戳 一一对应
     */
    public static void getIntervalTimeByDay(Long startTime, Long endTime, List<Long> beginDateList, List<Long> endDateList) {
        Date startDate = new Date(startTime);
        Date endDate = new Date(endTime);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        beginDateList.add(calendar.getTimeInMillis());
        while (calendar.getTimeInMillis() < endDate.getTime()) {
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            if(calendar.getTimeInMillis() < endDate.getTime()){
                endDateList.add(calendar.getTimeInMillis());
            } else {
                endDateList.add(endDate.getTime());
                break;
            }
            calendar.add(Calendar.DATE, 1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            beginDateList.add(calendar.getTimeInMillis());
        }
    }

    /**
     * 按照天分割一段时间
     *
     * @param startTime     开始时间戳(毫秒)
     * @param endTime       结束时间戳(毫秒)
     * @param beginDateList 开始段时间戳 和 结束段时间戳 一一对应
     * @param endDateList   结束段时间戳 和 开始段时间戳 一一对应
     */
    public static void getIntervalTimeByDay2(Long startTime, Long endTime, List<Long> beginDateList, List<Long> endDateList, int stHour, int edHour) {
        Date startDate = new Date(startTime);
        Date endDate = new Date(endTime);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        beginDateList.add(calendar.getTimeInMillis());
        int i = 0;
        while (calendar.getTimeInMillis() < endDate.getTime()) {
            if(i != 0 && stHour != 0) {
                calendar.add(Calendar.DATE, 1);
            }
            calendar.set(Calendar.HOUR_OF_DAY, edHour);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            if(calendar.getTimeInMillis() < endDate.getTime()){
                endDateList.add(calendar.getTimeInMillis());
            } else {
                endDateList.add(endDate.getTime());
                break;
            }
            calendar.set(Calendar.HOUR_OF_DAY, stHour);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            beginDateList.add(calendar.getTimeInMillis());
            i++;
        }
    }

    /**
     * 获取指定年月的第一天
     * @param date
     * @return
     */
    public static String getFirstDayOfMonth(String date) {
        String[] split = date.split("-");
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, Integer.valueOf(split[0]));
        //设置月份
        cal.set(Calendar.MONTH, Integer.valueOf(split[1]) - 1);
        //获取某月最小天数
        int firstDay = cal.getMinimum(Calendar.DATE);
        //设置日历中月份的最小天数
        cal.set(Calendar.DAY_OF_MONTH,firstDay);

        return sdf2.format(cal.getTime());
    }

    /**
     * 获取指定年月的最后一天
     * @param date
     * @return
     */
    public static String getLastDayOfMonth(String date) {
        String[] split = date.split("-");
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, Integer.valueOf(split[0]));
        //设置月份
        cal.set(Calendar.MONTH, Integer.valueOf(split[1]) - 1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DATE);
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);

        return sdf2.format(cal.getTime());
    }
}
